/*
 * Copyright (c) 2022, IMMORTA Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * - Neither the name of IMMORTA Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SPWM_REG_ACCESS_H
#define SPWM_REG_ACCESS_H

/*!
 * @file spwm_reg_access.h
 * @brief This file declares or defines spwm register access functions
 */

/*******Includes***************************************************************/
#include "spwm_drv.h"

/*******Definitions************************************************************/
/*! @brief All channel event flag */
#define SPWM_STATUS_CHF_Msk              (0xFFUL)

/*! @brief All channel level */
#define SPWM_STATUS_LVL_MASK             (0xFF00UL)

/*! @brief Dual channel config width */
#define SPWM_DUAL_CH_CONFIG_WIDTH        (8UL)

/*! @brief All fault flag mask */
#define SPWM_FAULT_FLAG_MASK             (0xFUL)

/*******APIs*******************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Enable/Disable the SPWM counter
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the SPWM counter
 *            - false: Disable the SPWM counter
 * @return None
 */
static inline void SPWM_REG_SetCntEn(SPWM_Type* regBase, bool enable)
{
    regBase->SC = (regBase->SC & ~SPWM_SC_CNTEN_Msk)
                  | ((uint32_t)enable << SPWM_SC_CNTEN_Pos);
}

/*!
 * @brief Set SPWM count mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] mode
 *            - 0: SPWM_UP_COUNT
 *            - 1: SPWM_UP_DOWN_COUNT
 * @return None
 */
static inline void SPWM_REG_SetCntMode(SPWM_Type* regBase, spwm_count_mode_t cntMode)
{
    regBase->SC = (regBase->SC & ~SPWM_SC_CPWMS_Msk)
                  | ((uint32_t)cntMode << SPWM_SC_CPWMS_Pos);
}

/*!
 * @brief Enable/Disable the SPWM overflow interrupt
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the overflow interrupt
 *            - false: Disable the overflow interrupt
 * @return None
 */
static inline void SPWM_REG_SetOverflowIntEn(SPWM_Type* regBase, bool enable)
{
    regBase->SC = (regBase->SC & ~SPWM_SC_COIE_Msk)
                  | ((uint32_t)enable << SPWM_SC_COIE_Pos);
}

/*!
 * @brief Enable/Disable the SPWM underflow interrupt
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the underflow interrupt
 *            - false: Disable the underflow interrupt
 * @return None
 */
static inline void SPWM_REG_SetUnderflowIntEn(SPWM_Type* regBase, bool enable)
{
    regBase->SC = (regBase->SC & ~SPWM_SC_CUIE_Msk)
                  | ((uint32_t)enable << SPWM_SC_CUIE_Pos);
}

/*!
 * @brief Set the SPWM overflow & underflow interrupt event ratio
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] ratio: Event ratio
 * @return None
 */
static inline void SPWM_REG_SetOverflowEventRatio(SPWM_Type* regBase, uint8_t ratio)
{
    uint32_t regValue = regBase->SC;

    regValue &= ~SPWM_SC_COFNUM_Msk;
    regValue |= (((uint32_t)ratio << SPWM_SC_COFNUM_Pos) & SPWM_SC_COFNUM_Msk);
    regBase->SC = regValue;
}

/*!
 * @brief Clear the SPWM overflow interrupt flag
 *
 * @param[in] regBase: The SPWM register base address
 * @return None
 */
static inline void SPWM_REG_ClrOverflowFlag(SPWM_Type* regBase)
{
    uint32_t regValue = regBase->SC;

    regValue &= ~(SPWM_SC_COF_Msk | SPWM_SC_CUF_Msk);
    regValue |= SPWM_SC_COF_Msk;
    regBase->SC = regValue;
}

/*!
 * @brief Get the SPWM overflow interrupt flag
 *
 * @param[in] regBase: The SPWM register base address
 * @return Overflow flag
 *         - true: Has overflowed
 *         - false: Has not overflowed
 */
static inline bool SPWM_REG_GetOverflowFlag(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->SC & SPWM_SC_COF_Msk) >> SPWM_SC_COF_Pos;

    return (bool)regValue;
}

/*!
 * @brief Clear the SPWM underflow interrupt flag
 *
 * @param[in] regBase: The SPWM register base address
 * @return None
 */
static inline void SPWM_REG_ClrUnderflowFlag(SPWM_Type* regBase)
{
    uint32_t regValue = regBase->SC;

    regValue &= ~(SPWM_SC_COF_Msk | SPWM_SC_CUF_Msk);
    regValue |= SPWM_SC_CUF_Msk;
    regBase->SC = regValue;
}

/*!
 * @brief Get the SPWM underflow interrupt flag
 *
 * @param[in] regBase: The SPWM register base address
 * @return Overflow flag
 *         - true: Has underflowed
 *         - false: Has not underflowed
 */
static inline bool SPWM_REG_GetUnderflowFlag(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->SC & SPWM_SC_CUF_Msk) >> SPWM_SC_CUF_Pos;

    return (bool)regValue;
}

/*!
 * @brief Set the SPWM prescaler value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] psc: Prescaler value
 * @return None
 */
static inline void SPWM_REG_SetPrescaler(SPWM_Type* regBase, uint8_t psc)
{
    regBase->SC = (regBase->SC & ~SPWM_SC_PSC_Msk)
                  | ((uint32_t)psc << SPWM_SC_PSC_Pos);
}

/*!
 * @brief Set the SPWM channel counter value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] cntValue: Counter value
 * @return None
 */
static inline void SPWM_REG_SetCounter(SPWM_Type* regBase, uint16_t cntValue)
{
    regBase->CNT = (uint32_t)cntValue;
}

/*!
 * @brief Get the SPWM counter current value
 *
 * @param[in] regBase: The SPWM register base address
 * @return Counter current value
 */
static inline uint16_t SPWM_REG_GetCounter(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = regBase->CNT;

    return (uint16_t)regValue;
}

/*!
 * @brief Set the SPWM counter modulo value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] modValue: Counter modulo value
 * @return None
 */
static inline void SPWM_REG_SetMod(SPWM_Type* regBase, uint16_t modValue)
{
    regBase->MOD = (uint32_t)modValue;
}

/*!
 * @brief Get the SPWM counter modulo value
 *
 * @param[in] regBase: The SPWM register base address
 * @return Counter modulo value
 */
static inline uint16_t SPWM_REG_GetMod(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = regBase->MOD;

    return (uint16_t)regValue;
}

/*!
 * @brief Set the SPWM counter initial value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] initVal: Counter initial value
 * @return None
 */
static inline void SPWM_REG_SetCntInitVal(SPWM_Type* regBase, uint16_t initVal)
{
    regBase->CNTIN = (uint32_t)initVal;
}

/*!
 * @brief Get the SPWM counter initial value
 *
 * @param[in] regBase: The SPWM register base address
 * @return Counter initial value
 */
static inline uint16_t SPWM_REG_GetCntInitVal(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = regBase->CNTIN;

    return (uint16_t)regValue;
}

/*!
 * @brief Enable/Disable the SPWM channel event reset function
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] enable
 *            - true: Enable the channel event reset
 *            - false: Disable the channel event reset
 * @return None
 */
static inline void SPWM_REG_SetChEventReset(SPWM_Type* regBase, spwm_channel_t channel, bool enable)
{
    regBase->CONTROLS[channel].CnSC = (regBase->CONTROLS[channel].CnSC & ~SPWM_C0SC_ICRST_Msk)
                                      | ((uint32_t)enable << SPWM_C0SC_ICRST_Pos);
}

/*!
 * @brief Set the SPWM Channel value match dir
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] dir
 *            - 0: SPWM_MATCH_DIR_DOWN
 *            - 1: SPWM_MATCH_DIR_UP
 * @return None
 */
static inline void SPWM_REG_SetChMatchDir(SPWM_Type* regBase, spwm_channel_t channel, spwm_match_dir_t dir)
{
    regBase->CONTROLS[channel].CnSC = (regBase->CONTROLS[channel].CnSC & ~SPWM_C0SC_DIR_Msk)
                                      | ((uint32_t)dir << SPWM_C0SC_DIR_Pos);
}

/*!
 * @brief Set the SPWM event edge level
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] level: 00, 01, 10, 11
 * @return None
 */
static inline void SPWM_REG_SetChEventEdgeLevel(SPWM_Type* regBase, spwm_channel_t channel, uint8_t levelMode)
{
    uint32_t regValue = regBase->CONTROLS[channel].CnSC;

    regValue &= ~SPWM_C0SC_ELS_Msk;
    regValue |= (((uint32_t)levelMode << SPWM_C0SC_ELS_Pos) & SPWM_C0SC_ELS_Msk);
    regBase->CONTROLS[channel].CnSC = regValue;
}

/*!
 * @brief Set the SPWM channel work mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] mode: 00, 01, 10, 11
 * @return None
 */
static inline void SPWM_REG_SetChMode(SPWM_Type* regBase, spwm_channel_t channel, uint8_t mode)
{
    uint32_t regValue = regBase->CONTROLS[channel].CnSC;

    regValue &= ~SPWM_C0SC_MSEL_Msk;
    regValue |= (((uint32_t)mode << SPWM_C0SC_MSEL_Pos) & SPWM_C0SC_MSEL_Msk);
    regBase->CONTROLS[channel].CnSC = regValue;
}

/*!
 * @brief Enable/Disable the SPWM channel event interrupt
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] enable
 *            - true: Enable the channel event interrupt
 *            - false: Disable the channel event interrupt
 * @return None
 */
static inline void SPWM_REG_SetChEventIntEn(SPWM_Type* regBase, spwm_channel_t channel, bool enable)
{
    regBase->CONTROLS[channel].CnSC = (regBase->CONTROLS[channel].CnSC & ~SPWM_C0SC_CHIE_Msk)
                                      | ((uint32_t)enable << SPWM_C0SC_CHIE_Pos);
}

/*!
 * @brief Clear the SPWM channel event interrupt flag
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @return None
 */
static inline void SPWM_REG_ClrChFlag(SPWM_Type* regBase, spwm_channel_t channel)
{
    regBase->CONTROLS[channel].CnSC |= SPWM_C0SC_CHF_Msk;
}

/*!
 * @brief Get the SPWM channel event interrupt flag
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @return Channel event interrupt flag
 *         - true: Has occured channel event
 *         - false: Has not occured channel event
 */
static inline bool SPWM_REG_GetChFlag(SPWM_Type* regBase, spwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = (regBase->CONTROLS[channel].CnSC & SPWM_C0SC_CHF_Msk) >> SPWM_C0SC_CHF_Pos;

    return (bool)regValue;
}

/*!
 * @brief Set the SPWM channel interrupt event ratio
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] ratio
 *            - 0: SPWM_CH_EVENT_RATIO_1
 *            - 1: SPWM_CH_EVENT_RATIO_2
 *            - 2: SPWM_CH_EVENT_RATIO_4
 *            - 3: SPWM_CH_EVENT_RATIO_8
 * @return None
 */
static inline void SPWM_REG_SetChEventRatio(SPWM_Type* regBase, spwm_channel_t channel, spwm_ch_event_ratio_t ratio)
{
    regBase->CONTROLS[channel].CnSC = (regBase->CONTROLS[channel].CnSC & ~SPWM_C0SC_CHFPSC_Msk)
                                      | ((uint32_t)ratio << SPWM_C0SC_CHFPSC_Pos);
}

/*!
 * @brief Set the SPWM channel value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] chVal: Channel value
 * @return None
 */
static inline void SPWM_REG_SetChannelValue(SPWM_Type* regBase, spwm_channel_t channel, uint16_t chVal)
{
    regBase->CONTROLS[channel].CnV = (uint32_t)chVal;
}

/*!
 * @brief Get the SPWM channel value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @return Channel value
 */
static inline uint16_t SPWM_REG_GetChannelValue(SPWM_Type* regBase, spwm_channel_t channel)
{
    uint32_t regValue = 0U;

    regValue = regBase->CONTROLS[channel].CnV & SPWM_C0V_VAL_Msk;

    return (uint16_t)regValue;
}

/*!
 * @brief Get the SPWM all channel event status
 *
 * @param[in] regBase: The SPWM register base address
 * @return All channel event status
 */
static inline uint8_t SPWM_REG_GetChStatus(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = regBase->STATUS & SPWM_STATUS_CHF_Msk;

    return (uint8_t)regValue;
}

/*!
 * @brief Clear the SPWM channel event status
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] chMask: Channel mask
 * @return None
 */
static inline void SPWM_REG_ClrChStatus(SPWM_Type* regBase, uint8_t chMask)
{
    uint32_t regValue = regBase->STATUS;

    regValue &= ~SPWM_STATUS_CHF_Msk;
    regValue |= (uint32_t)chMask;
    regBase->STATUS = regValue;
}

/*!
 * @brief Get the SPWM all channel level
 *
 * @param[in] regBase: The SPWM register base address
 * @return All channel level
 */
static inline uint8_t SPWM_REG_GetChLevel(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->STATUS & SPWM_STATUS_LVL_MASK) >> SPWM_STATUS_CH0LVL_Pos;

    return (uint8_t)regValue;
}

/*!
 * @brief Enable/Disable the SPWM register sync
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable register sync
 *            - false: Disable register sync
 * @return None
 */
static inline void SPWM_REG_SetSyncEnable(SPWM_Type* regBase, bool enable)
{
    regBase->MODE = (regBase->MODE & ~SPWM_MODE_PWMSYNCEN_Msk)
                    | ((uint32_t)enable << SPWM_MODE_PWMSYNCEN_Pos);
}

/*!
 * @brief Enable/Disable the SPWM output init function
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the output init function
 *            - false: Disable the output init function
 * @return None
 */
static inline void SPWM_REG_SetOutputInit(SPWM_Type* regBase, bool enable)
{
    regBase->MODE = (regBase->MODE & ~SPWM_MODE_INIT_Msk)
                    | ((uint32_t)enable << SPWM_MODE_INIT_Pos);
}

/*!
 * @brief Enable/Disable the SPWM write protect
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the write protect
 *            - false: Disable the write protect
 * @return None
 */
static inline void SPWM_REG_SetWriteProtect(SPWM_Type* regBase, bool enable)
{
    if (enable) {
        regBase->FMS |= SPWM_FMS_WPEN_Msk;
    } else {
        regBase->MODE |= SPWM_MODE_WPDIS_Msk;
    }
}

/*!
 * @brief Enable/Disable the SPWM register read from sync buffer
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Read from sync buffer
 *            - false: Read out the actual active register configuration
 * @return None
 */
static inline void SPWM_REG_SetReadBuff(SPWM_Type* regBase, bool enable)
{
    regBase->MODE = (regBase->MODE & ~SPWM_MODE_BUFFRD_Msk)
                    | ((uint32_t)enable << SPWM_MODE_BUFFRD_Pos);
}

/*!
 * @brief Set the SPWM fault mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] mode
 *            - 0: SPWM_FAULT_CTRL_MANUAL
 *            - 1: SPWM_FAULT_CTRL_AUTO
 * @return None
 */
static inline void SPWM_REG_SetFaultMode(SPWM_Type* regBase, spwm_fault_ctrl_mode_t mode)
{
    regBase->MODE = (regBase->MODE & ~SPWM_MODE_FAULTM_Msk)
                    | ((uint32_t)mode << SPWM_MODE_FAULTM_Pos);
}

/*!
 * @brief Enable/Disable the SPWM fault function
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable fault mode
 *            - false: Disable fault mode
 * @return None
 */
static inline void SPWM_REG_SetFaultEnable(SPWM_Type* regBase, bool enable)
{
    regBase->MODE = (regBase->MODE & ~SPWM_MODE_FAULTEN_Msk)
                    | ((uint32_t)enable << SPWM_MODE_FAULTEN_Pos);
}

/*!
 * @brief Enable/Disable the SPWM fault interrupt
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable fault interrupt
 *            - false: Disable fault interrupt
 * @return None
 */
static inline void SPWM_REG_SetFaultIntEnable(SPWM_Type* regBase, bool enable)
{
    regBase->MODE = (regBase->MODE & ~SPWM_MODE_FAULTIE_Msk)
                    | ((uint32_t)enable << SPWM_MODE_FAULTIE_Pos);
}

/*!
 * @brief Enable/Disable the SPWM hall mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable hall mode
 *            - false: Disable hall mode
 * @return None
 */
static inline void SPWM_REG_SetHallMode(SPWM_Type* regBase, bool enable)
{
    regBase->MODE = (regBase->MODE & ~SPWM_MODE_HALL_Msk)
                    | ((uint32_t)enable << SPWM_MODE_HALL_Pos);
}

/*!
 * @brief Enable/Disable the SPWM min load point
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the min load point
 *            - false: Disable the min load point
 * @return None
 */
static inline void SPWM_REG_SetMinLoadPoint(SPWM_Type* regBase, bool enable)
{
    regBase->SYNC = (regBase->SYNC & ~SPWM_SYNC_CNTMIN_Msk)
                    | ((uint32_t)enable << SPWM_SYNC_CNTMIN_Pos);
}

/*!
 * @brief Enable/Disable the SPWM max load point
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the max load point
 *            - false: Disable the max load point
 * @return None
 */
static inline void SPWM_REG_SetMaxLoadPoint(SPWM_Type* regBase, bool enable)
{
    regBase->SYNC = (regBase->SYNC & ~SPWM_SYNC_CNTMAX_Msk)
                    | ((uint32_t)enable << SPWM_SYNC_CNTMAX_Pos);
}

/*!
 * @brief Enable/Disable the SPWM output mask sync
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable output mask sync
 *            - false: Disable output mask sync
 * @return None
 */
static inline void SPWM_REG_SetOutputMaskSyncEn(SPWM_Type* regBase, bool enable)
{
    regBase->SYNC = (regBase->SYNC & ~SPWM_SYNC_SYNCHOM_Msk)
                    | ((uint32_t)enable << SPWM_SYNC_SYNCHOM_Pos);
}

/*!
 * @brief Enable/Disable the SPWM hardware trigger source 0 sync
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable hardware trigger source 0 sync
 *            - false: Disable hardware trigger source 0 sync
 * @return None
 */
static inline void SPWM_REG_SetHardwareTrig0En(SPWM_Type* regBase, bool enable)
{
    regBase->SYNC = (regBase->SYNC & ~SPWM_SYNC_TRIG0_Msk)
                    | ((uint32_t)enable << SPWM_SYNC_TRIG0_Pos);
}

/*!
 * @brief Enable/Disable the SPWM hardware trigger source 1 sync
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable hardware trigger source 1 sync
 *            - false: Disable hardware trigger source 1 sync
 * @return None
 */
static inline void SPWM_REG_SetHardwareTrig1En(SPWM_Type* regBase, bool enable)
{
    regBase->SYNC = (regBase->SYNC & ~SPWM_SYNC_TRIG1_Msk)
                    | ((uint32_t)enable << SPWM_SYNC_TRIG1_Pos);
}

/*!
 * @brief Set software trigger to sync register
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Set Software trigger signal to high
 *            - false: Set Software trigger signal to low
 * @return None
 */
static inline void SPWM_REG_SetSoftwareTriggerSync(SPWM_Type* regBase, bool enable)
{
    regBase->SYNC = (regBase->SYNC & ~SPWM_SYNC_SWSYNC_Msk)
                    | ((uint32_t)enable << SPWM_SYNC_SWSYNC_Pos);
}

/*!
 * @brief Set the SPWM output init level
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] level
 *            - 0: SPWM_LOW_LEVEL
 *            - 1: SPWM_HIGH_LEVEL
 * @return None
 */
static inline void SPWM_REG_SetOutputInitLevel(SPWM_Type* regBase, spwm_channel_t channel, spwm_output_level_t level)
{
    uint32_t regValue = regBase->OUTINIT;

    regValue &= ~(SPWM_OUTINIT_CH0OI_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)level << (SPWM_OUTINIT_CH0OI_Pos + (uint32_t)channel));
    regBase->OUTINIT = regValue;
}

/*!
 * @brief Enable/Disable the SPWM output mask function
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] enable
 *            - true: Enable the output mask
 *            - false: Disable the output mask
 * @return None
 */
static inline void SPWM_REG_SetOutputMask(SPWM_Type* regBase, spwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->OUTMASK;

    regValue &= ~(SPWM_OUTMASK_CH0OM_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (SPWM_OUTMASK_CH0OM_Pos + (uint32_t)channel));
    regBase->OUTMASK = regValue;
}

/*!
 * @brief Enable/Disable the SPWM dual channel combine
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] enable
 *            - true: Enable dual channel combine
 *            - false: Disable dual channel combine
 * @return None
 */
static inline void SPWM_REG_SetDualChCombine(SPWM_Type* regBase, spwm_dual_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->COMBINE;

    regValue &= ~(SPWM_COMBINE_COMBINE0_Msk << ((uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (SPWM_COMBINE_COMBINE0_Pos + (uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regBase->COMBINE = regValue;
}

/*!
 * @brief Enable/Disable the SPWM dual channel complement
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] enable
 *            - true: Enable dual channel complement
 *            - false: Disable dual channel complement
 * @return None
 */
static inline void SPWM_REG_SetDualChComplement(SPWM_Type* regBase, spwm_dual_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->COMBINE;

    regValue &= ~(SPWM_COMBINE_COMP0_Msk << ((uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (SPWM_COMBINE_COMP0_Pos + (uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regBase->COMBINE = regValue;
}

/*!
 * @brief Enable/Disable the SPWM dual channel capture
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] enable
 *            - true: Enable dual channel capture
 *            - false: Disable dual channel capture
 * @return None
 */
static inline void SPWM_REG_SetDualEdgeCapture(SPWM_Type* regBase, spwm_dual_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->COMBINE;

    regValue &= ~(SPWM_COMBINE_DECAPEN0_Msk << ((uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (SPWM_COMBINE_DECAPEN0_Pos + (uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regBase->COMBINE = regValue;
}

/*!
 * @brief Enable/Disable the SPWM decap
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] enable
 *            - true: Enable decap
 *            - false: Disable decap
 * @return None
 */
static inline void SPWM_REG_SetDualChDecap(SPWM_Type* regBase, spwm_dual_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->COMBINE;

    regValue &= ~(SPWM_COMBINE_DECAP0_Msk << ((uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (SPWM_COMBINE_DECAP0_Pos + (uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regBase->COMBINE = regValue;
}

/*!
 * @brief Enable/Disable the SPWM dual channel dead time insert
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] enable
 *            - true: Enable dual channel dead time insert
 *            - false: Disable dual channel dead time insert
 * @return None
 */
static inline void SPWM_REG_SetDualChDeadtime(SPWM_Type* regBase, spwm_dual_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->COMBINE;

    regValue &= ~(SPWM_COMBINE_DTEN0_Msk << ((uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (SPWM_COMBINE_DTEN0_Pos + (uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regBase->COMBINE = regValue;
}

/*!
 * @brief Enable/Disable the SPWM dual channel CnV sync
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] enable
 *            - true: Enable dual channel sync
 *            - false: Disable dual channel sync
 * @return None
 */
static inline void SPWM_REG_SetCnvSync(SPWM_Type* regBase, spwm_dual_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->COMBINE;

    regValue &= ~(SPWM_COMBINE_SYNCEN0_Msk << ((uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (SPWM_COMBINE_SYNCEN0_Pos + (uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regBase->COMBINE = regValue;
}

/*!
 * @brief Enable/Disable the SPWM dual channel fault control
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] enable
 *            - true: Enable dual channel fault control
 *            - false: Disable dual channel fault control
 * @return None
 */
static inline void SPWM_REG_SetDualChFault(SPWM_Type* regBase, spwm_dual_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->COMBINE;

    regValue &= ~(SPWM_COMBINE_FAULTEN0_Msk << ((uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (SPWM_COMBINE_FAULTEN0_Pos + (uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regBase->COMBINE = regValue;
}

/*!
 * @brief Enable/Disable the SPWM dual channel symmetric
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] enable
 *            - true: Enable dual channel symmetric
 *            - false: Disable dual channel symmetric
 * @return None
 */
static inline void SPWM_REG_SetDualChSymm(SPWM_Type* regBase, spwm_dual_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->COMBINE;

    regValue &= ~(SPWM_COMBINE_SYMM0_Msk << ((uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regValue |= ((uint32_t)enable << (SPWM_COMBINE_SYMM0_Pos + (uint32_t)channel * SPWM_DUAL_CH_CONFIG_WIDTH));
    regBase->COMBINE = regValue;
}

/*!
 * @brief Get the SPWM all fault input event status
 *
 * @param[in] regBase: The SPWM register base address
 * @return Fault event flag
 */
static inline uint8_t SPWM_REG_GetFaultStatus(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = regBase->FMS & SPWM_FAULT_FLAG_MASK;

    return (uint8_t)regValue;
}

/*!
 * @brief Clear the SPWM fault event flag
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] mask: Fault event flag that need be cleared
 * @return None
 */
static inline void SPWM_REG_ClrFaultStatus(SPWM_Type* regBase, uint8_t mask)
{
    uint32_t regValue = regBase->FMS;

    regValue &= ~(SPWM_FAULT_FLAG_MASK | SPWM_FMS_FAULTF_Msk);
    regValue |= (mask & SPWM_FAULT_FLAG_MASK);
    regBase->FMS = regValue;
}

/*!
 * @brief Get the SPWM fault input status
 *
 * @param[in] regBase: The SPWM register base address
 * @return Fault input status
 */
static inline bool SPWM_REG_GetFaultInput(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->FMS & SPWM_FMS_FAULTIN_Msk) >> SPWM_FMS_FAULTIN_Pos;

    return (bool)regValue;
}

/*!
 * @brief Get the SPWM FAULTF flag
 *
 * @param[in] regBase: The SPWM register base address
 * @return FAULTF flag
 */
static inline bool SPWM_REG_GetFAULTF(SPWM_Type* regBase)
{
    uint32_t regValue = 0U;

    regValue = (regBase->FMS & SPWM_FMS_FAULTF_Msk) >> SPWM_FMS_FAULTF_Pos;

    return (bool)regValue;
}

/*!
 * @brief Clear the SPWM FAULTF flag
 *
 * @param[in] regBase: The SPWM register base address
 * @return None
 */
static inline void SPWM_REG_ClrFAULTF(SPWM_Type* regBase)
{
    uint32_t regValue = regBase->FMS;

    regValue &= ~(SPWM_FAULT_FLAG_MASK | SPWM_FMS_FAULTF_Msk);
    regValue |= SPWM_FMS_FAULTF_Msk;
    regBase->FMS = regValue;
}

/*!
 * @brief Enable/Disable the SPWM channel event match trigger
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] enable
 *            - true: Enable the channel event match trigger
 *            - false: Disable the channel event match trigger
 * @return None
 */
static inline void SPWM_REG_SetChMatchTrigger(SPWM_Type* regBase, spwm_channel_t channel, bool enable)
{
    uint32_t regValue =  regBase->EXTTRIG;

    regValue &= ~(SPWM_EXTTRIG_CH0MATCHTRIG_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (SPWM_EXTTRIG_CH0MATCHTRIG_Pos + (uint32_t)channel));
    regBase->EXTTRIG = regValue;
}

/*!
 * @brief Enable/Disable the SPWM Min trigger
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the min trigger
 *            - false: Disable the min trigger
 * @return None
 */
static inline void SPWM_REG_SetMinTrigger(SPWM_Type* regBase, bool enable)
{
    regBase->EXTTRIG = (regBase->EXTTRIG & ~SPWM_EXTTRIG_MINTRIG_Msk)
                       | ((uint32_t)enable << SPWM_EXTTRIG_MINTRIG_Pos);
}

/*!
 * @brief Enable/Disable the SPWM max trigger
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the max trigger
 *            - false: Disable the max trigger
 * @return None
 */
static inline void SPWM_REG_SetMaxTrigger(SPWM_Type* regBase, bool enable)
{
    regBase->EXTTRIG = (regBase->EXTTRIG & ~SPWM_EXTTRIG_MAXTRIG_Msk)
                       | ((uint32_t)enable << SPWM_EXTTRIG_MAXTRIG_Pos);
}

/*!
 * @brief Set the SPWM external trigger ratio
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] ratio
 *            - 0: SPWM_TRIGGER_RATIO_1
 *            - 1: SPWM_TRIGGER_RATIO_2
 *            - 2: SPWM_TRIGGER_RATIO_3
 *            - 3: SPWM_TRIGGER_RATIO_4
 *            - 4: SPWM_TRIGGER_RATIO_5
 *            - 5: SPWM_TRIGGER_RATIO_6
 *            - 6: SPWM_TRIGGER_RATIO_7
 *            - 7: SPWM_TRIGGER_RATIO_8
 * @return None
 */
static inline void SPWM_REG_SetExternalTriggerRatio(SPWM_Type* regBase, spwm_trigger_ratio_t ratio)
{
    regBase->EXTTRIG = (regBase->EXTTRIG & ~SPWM_EXTTRIG_TRIGPSC_Msk)
                       | ((uint32_t)ratio << SPWM_EXTTRIG_TRIGPSC_Pos);
}

/*!
 * @brief Set the SPWM channel polarity
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] polarity
 *            - 0: SPWM_OUTPUT_POLARITY_ACTIVE_HIGH
 *            - 1: SPWM_OUTPUT_POLARITY_ACTIVE_LOW
 * @return None
 */
static inline void SPWM_REG_SetChPOL(SPWM_Type* regBase, spwm_channel_t channel, spwm_active_output_polarity_t polarity)
{
    uint32_t regValue = regBase->POL;

    regValue &= ~(SPWM_POL_CH0POL_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)polarity << (SPWM_POL_CH0POL_Pos + (uint32_t)channel));
    regBase->POL = regValue;
}

/*!
 * @brief Set the SPWM input filter value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] filterVal: input filter value
 * @return None
 */
static inline void SPWM_REG_SetInputFilterVal(SPWM_Type* regBase, spwm_channel_t channel, uint8_t filterVal)
{
    uint32_t regValue = regBase->FILTER;

    regValue &= ~(SPWM_FILTER_CH0FVAL_Msk << (SPWM_FILTER_CH1FVAL_Pos * (uint32_t)channel));
    regValue |= ((uint32_t)filterVal << (SPWM_FILTER_CH1FVAL_Pos * (uint32_t)channel));
    regBase->FILTER = regValue;
}

/*!
 * @brief Set the SPWM input filter prescaler value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] filtePsc: input filter prescaler value
 * @return None
 */
static inline void SPWM_REG_SetInputFilterPsc(SPWM_Type* regBase, spwm_input_filter_psc_t filtePsc)
{
    regBase->FILTER = (regBase->FILTER & ~SPWM_FILTER_FILTPSC_Msk)
                      | ((uint32_t)filtePsc << SPWM_FILTER_FILTPSC_Pos);
}

/*!
 * @brief Enable/Disable the SPWM fault input
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] input
 *            - 0: SPWM_FAULT_INPUT_0
 *            - 1: SPWM_FAULT_INPUT_1
 *            - 2: SPWM_FAULT_INPUT_2
 *            - 3: SPWM_FAULT_INPUT_3
 * @param[in] enable
 *            - true: Enable the fault input
 *            - false: Disable the fault input
 * @return None
 */
static inline void SPWM_REG_SetFaultInput(SPWM_Type* regBase, spwm_fault_input_t input, bool enable)
{
    uint32_t regValue = regBase->FLTCTRL;

    regValue &= ~(SPWM_FLTCTRL_FAULT0EN_Msk << (uint32_t)input);
    regValue |= ((uint32_t)enable << (SPWM_FLTCTRL_FAULT0EN_Pos + (uint32_t)input));
    regBase->FLTCTRL = regValue;
}

/*!
 * @brief Enable/Disable the SPWM fault input filter
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] input
 *            - 0: SPWM_FAULT_INPUT_0
 *            - 1: SPWM_FAULT_INPUT_1
 *            - 2: SPWM_FAULT_INPUT_2
 *            - 3: SPWM_FAULT_INPUT_3
 * @param[in] enable
 *            - true: Enable the fault input filter
 *            - false: Disable the fault input filter
 * @return None
 */
static inline void SPWM_REG_SetFaultInputFilterEn(SPWM_Type* regBase, spwm_fault_input_t input, bool enable)
{
    uint32_t regValue = regBase->FLTCTRL;

    regValue &= ~(SPWM_FLTCTRL_FFLTR0EN_Msk << (uint32_t)input);
    regValue |= ((uint32_t)enable << (SPWM_FLTCTRL_FFLTR0EN_Pos + (uint32_t)input));
    regBase->FLTCTRL = regValue;
}

/*!
 * @brief Set the SPWM fault input filter value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] filterVal: filter value
 * @return None
 */
static inline void SPWM_REG_SetFaultInputFilterVal(SPWM_Type* regBase, uint8_t filterVal)
{
    regBase->FLTCTRL = (regBase->FLTCTRL & ~SPWM_FLTCTRL_FFVAL_Msk)
                       | ((uint32_t)filterVal << SPWM_FLTCTRL_FFVAL_Pos);
}

/*!
 * @brief Enable/Disable the SPWM fault HIZ output
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable fault HIZ output
 *            - false: Disable fault HIZ output
 * @return None
 */
static inline void SPWM_REG_SetFaultHizOutput(SPWM_Type* regBase, bool enable)
{
    regBase->FLTCTRL = (regBase->FLTCTRL & ~SPWM_FLTCTRL_HIZ_Msk)
                       | ((uint32_t)enable << SPWM_FLTCTRL_HIZ_Pos);
}

/*!
 * @brief Set the SPWM fault polarity
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] input
 *            - 0: SPWM_FAULT_INPUT_0
 *            - 1: SPWM_FAULT_INPUT_1
 *            - 2: SPWM_FAULT_INPUT_2
 *            - 3: SPWM_FAULT_INPUT_3
 * @param[in] pol
 *            - 0: SPWM_INPUT_POLARITY_ACTIVE_HIGH
 *            - 1: SPWM_INPUT_POLARITY_ACTIVE_LOW
 * @return None
 */
static inline void SPWM_REG_SetFaultPolarity(SPWM_Type* regBase,
                                             spwm_fault_input_t input,
                                             spwm_fault_input_polarity_active_t pol)
{
    uint32_t regValue = regBase->FLTPOL;

    regValue &= ~(SPWM_FLTPOL_FLT0POL_Msk << (SPWM_FLTPOL_FLT0POL_Pos + (uint32_t)input));
    regValue |= ((uint32_t)pol << (SPWM_FLTPOL_FLT0POL_Pos + (uint32_t)input));
    regBase->FLTPOL = regValue;
}

/*!
 * @brief Enable/Disable the SPWM global time base
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the global time base
 *            - false: Disable the global time base
 * @return None
 */
static inline void SPWM_REG_SetGlobalTimeBaseEnable(SPWM_Type* regBase, bool enable)
{
    regBase->CONF = (regBase->CONF & ~SPWM_CONF_GTBEEN_Msk)
                    | ((uint32_t)enable << SPWM_CONF_GTBEEN_Pos);
}

/*!
 * @brief Enable/Disable the SPWM global time base ouput
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable the global time base ouput
 *            - false: Disable the global time base ouput
 * @return None
 */
static inline void SPWM_REG_SetGlobalTimeBaseOutput(SPWM_Type* regBase, bool enable)
{
    regBase->CONF = (regBase->CONF & ~SPWM_CONF_GTBEOUT_Msk)
                    | ((uint32_t)enable << SPWM_CONF_GTBEOUT_Pos);
}

/*!
 * @brief Enable/Disable the SPWM hardware trigger sync mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: SPWM not clears the TRIGj bit when the hardware trigger j is detected
 *            - false: SPWM clears the TRIGj bit when the hardware trigger j is detected
 * @return None
 */
static inline void SPWM_REG_SetHwTriggerSyncMode(SPWM_Type* regBase, bool enable)
{
    regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_HWTRIGMODE_Msk)
                       | ((uint32_t)enable << SPWM_SYNCONF_HWTRIGMODE_Pos);
}

/*!
 * @brief Enable/Disable the SPWM invert sync
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable invert sync
 *            - false: Disable invert sync
 * @return None
 */
static inline void SPWM_REG_SetInvertSyncMode(SPWM_Type* regBase, bool enable)
{
    regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_INVC_Msk)
                       | ((uint32_t)enable << SPWM_SYNCONF_INVC_Pos);
}

/*!
 * @brief Enable/Disable the SPWM software ouput control sync
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] enable
 *            - true: Enable software ouput control sync
 *            - false: Disable software ouput control sync
 * @return None
 */
static inline void SPWM_REG_SetSWOCTRLSyncMode(SPWM_Type* regBase, bool enable)
{
    regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_SWOC_Msk)
                       | ((uint32_t)enable << SPWM_SYNCONF_SWOC_Pos);
}

/*!
 * @brief Set the SPWM counter sync mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] mode
 *            - 0: SPWM_SYNC_TRIGGER_SOFTWARE
 *            - 1: SPWM_SYNC_TRIGGER_HARDWARE
 * @param[in] enable
 *            - true: Enable counter software or hardware sync
 *            - false: Disable counter software or hardware sync
 * @return None
 */
static inline void SPWM_REG_SetCounterSyncTriggerMode(SPWM_Type* regBase, spwm_sync_trigger_mode_t mode, bool enable)
{
    if (SPWM_SYNC_TRIGGER_SOFTWARE == mode) {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_SWRSTCNT_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_SWRSTCNT_Pos);
    } else {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_HWRSTCNT_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_HWRSTCNT_Pos);
    }
}

/*!
 * @brief Set the SPWM MOD,CNTIN,CNV sync mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] mode
 *            - 0: SPWM_SYNC_TRIGGER_SOFTWARE
 *            - 1: SPWM_SYNC_TRIGGER_HARDWARE
 * @param[in] enable
 *            - true: Enable MOD,CNTIN,CNV software or hardware sync
 *            - false: Disable MOD,CNTIN,CNV software or hardware sync
 * @return None
 */
static inline void SPWM_REG_SetModSyncTriggerMode(SPWM_Type* regBase, spwm_sync_trigger_mode_t mode, bool enable)
{
    if (SPWM_SYNC_TRIGGER_SOFTWARE == mode) {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_SWWRBUF_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_SWWRBUF_Pos);
    } else {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_HWWRBUF_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_HWWRBUF_Pos);
    }
}

/*!
 * @brief Set the SPWM output mask sync mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] mode
 *            - 0: SPWM_SYNC_TRIGGER_SOFTWARE
 *            - 1: SPWM_SYNC_TRIGGER_HARDWARE
 * @param[in] enable
 *            - true: Enable output mask software or hardware sync
 *            - false: Disable output mask software or hardware sync
 * @return None
 */
static inline void SPWM_REG_SetOutputMaskSyncTriggerMode(SPWM_Type* regBase, spwm_sync_trigger_mode_t mode, bool enable)
{
    if (SPWM_SYNC_TRIGGER_SOFTWARE == mode) {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_SWOM_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_SWOM_Pos);
    } else {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_HWOM_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_HWOM_Pos);
    }
}

/*!
 * @brief Set the SPWM invert sync mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] mode
 *            - 0: SPWM_SYNC_TRIGGER_SOFTWARE
 *            - 1: SPWM_SYNC_TRIGGER_HARDWARE
 * @param[in] enable
 *            - true: Enable invert software or hardware sync
 *            - false: Disable invert software or hardware sync
 * @return None
 */
static inline void SPWM_REG_SetInvertSyncTriggerMode(SPWM_Type* regBase, spwm_sync_trigger_mode_t mode, bool enable)
{
    if (SPWM_SYNC_TRIGGER_SOFTWARE == mode) {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_SWINVC_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_SWINVC_Pos);
    } else {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_HWINVC_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_HWINVC_Pos);
    }
}

/*!
 * @brief Set the SPWM software output control sync mode
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] mode
 *            - 0: SPWM_SYNC_TRIGGER_SOFTWARE
 *            - 1: SPWM_SYNC_TRIGGER_HARDWARE
 * @param[in] enable
 *            - true: Enable software output control software or hardware sync
 *            - false: Disable software output control software or hardware sync
 * @return None
 */
static inline void SPWM_REG_SetSWOCTRLSyncTriggerMode(SPWM_Type* regBase, spwm_sync_trigger_mode_t mode, bool enable)
{
    if (SPWM_SYNC_TRIGGER_SOFTWARE == mode) {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_SWSOC_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_SWSOC_Pos);
    } else {
        regBase->SYNCONF = (regBase->SYNCONF & ~SPWM_SYNCONF_HWSOC_Msk)
                           | ((uint32_t)enable << SPWM_SYNCONF_HWSOC_Pos);
    }
}

/*!
 * @brief Enable/Disable the SPWM dual channel invert
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] enable
 *            - true: Enable dual channel invert
 *            - false: Disable dual channel invert
 * @return None
 */
static inline void SPWM_REG_SetDualChInvert(SPWM_Type* regBase, spwm_dual_channel_t channel, bool enable)
{
    regBase->INVCTRL = (regBase->INVCTRL & ~(SPWM_INVCTRL_INV0EN_Msk << (uint32_t)channel))
                       | ((uint32_t)enable << (SPWM_INVCTRL_INV0EN_Pos + (uint32_t)channel));
}

/*!
 * @brief Enable/Disable the SPWM software output control
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] enable
 *            - true: Enable software output control
 *            - false: Disable software output control
 * @return None
 */
static inline void SPWM_REG_SetSoftwareControlEn(SPWM_Type* regBase, spwm_channel_t channel, bool enable)
{
    uint32_t regValue = regBase->SWOCTRL;

    regValue &= ~(SPWM_SWOCTRL_CH0OC_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)enable << (SPWM_SWOCTRL_CH0OC_Pos + (uint32_t)channel));
    regBase->SWOCTRL = regValue;
}

/*!
 * @brief Set the SPWM software output control level
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH0~7)
 * @param[in] level
 *            - 0: SPWM_LOW_LEVEL
 *            - 1: SPWM_HIGH_LEVEL
 * @return None
 */
static inline void SPWM_REG_SetSoftwareControlLevel(SPWM_Type* regBase, spwm_channel_t channel, spwm_output_level_t level)
{
    uint32_t regValue = regBase->SWOCTRL;

    regValue &= ~(SPWM_SWOCTRL_CH0OCV_Msk << (uint32_t)channel);
    regValue |= ((uint32_t)level << (SPWM_SWOCTRL_CH0OCV_Pos + (uint32_t)channel));
    regBase->SWOCTRL = regValue;
}

/*!
 * @brief Set the SPWM dual channel dead time value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] deadtimeVal: Dead time value
 * @return None
 */
static inline void SPWM_REG_SetDeadtimeVal(SPWM_Type* regBase, spwm_dual_channel_t channel, uint16_t deadtimeVal)
{
    switch (channel) {
        case SPWM_DUAL_CH_0:
            regBase->DEADTIME0 = (regBase->DEADTIME0 & ~SPWM_DEADTIME0_DTVAL0_Msk)
                                 | (((uint32_t)deadtimeVal << SPWM_DEADTIME0_DTVAL0_Pos) & SPWM_DEADTIME0_DTVAL0_Msk);
            break;

        case SPWM_DUAL_CH_1:
            regBase->DEADTIME0 = (regBase->DEADTIME0 & ~SPWM_DEADTIME0_DTVAL1_Msk)
                                 | (((uint32_t)deadtimeVal << SPWM_DEADTIME0_DTVAL1_Pos) & SPWM_DEADTIME0_DTVAL1_Msk);
            break;

        case SPWM_DUAL_CH_2:
            regBase->DEADTIME1 = (regBase->DEADTIME1 & ~SPWM_DEADTIME1_DTVAL2_Msk)
                                 | (((uint32_t)deadtimeVal << SPWM_DEADTIME1_DTVAL2_Pos) & SPWM_DEADTIME1_DTVAL2_Msk);
            break;

        case SPWM_DUAL_CH_3:
            regBase->DEADTIME1 = (regBase->DEADTIME1 & ~SPWM_DEADTIME1_DTVAL3_Msk)
                                 | (((uint32_t)deadtimeVal << SPWM_DEADTIME1_DTVAL3_Pos) & SPWM_DEADTIME1_DTVAL3_Msk);
            break;

        default:
            break;
    }
}

/*!
 * @brief Set the SPWM dual channel dead time prescaler
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM dual channel(SPWM_DUAL_CH_0~3)
 * @param[in] deadtimePsc: Dead time prescaler value
 * @return None
 */
static inline void SPWM_REG_SetDeadtimePsc(SPWM_Type* regBase, spwm_dual_channel_t channel, spwm_deadtime_psc_t deadtimePsc)
{
    switch (channel) {
        case SPWM_DUAL_CH_0:
            regBase->DEADTIME0 = (regBase->DEADTIME0 & ~SPWM_DEADTIME0_DTPS0_Msk)
                                 | ((uint32_t)deadtimePsc << SPWM_DEADTIME0_DTPS0_Pos);
            break;

        case SPWM_DUAL_CH_1:
            regBase->DEADTIME0 = (regBase->DEADTIME0 & ~SPWM_DEADTIME0_DTPS1_Msk)
                                 | ((uint32_t)deadtimePsc << SPWM_DEADTIME0_DTPS1_Pos);
            break;

        case SPWM_DUAL_CH_2:
            regBase->DEADTIME1 = (regBase->DEADTIME1 & ~SPWM_DEADTIME1_DTPS2_Msk)
                                 | ((uint32_t)deadtimePsc << SPWM_DEADTIME1_DTPS2_Pos);
            break;

        case SPWM_DUAL_CH_3:
            regBase->DEADTIME1 = (regBase->DEADTIME1 & ~SPWM_DEADTIME1_DTPS3_Msk)
                                 | ((uint32_t)deadtimePsc << SPWM_DEADTIME1_DTPS3_Pos);
            break;

        default:
            break;
    }
}

/*!
 * @brief Set the SPWM channel dither value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] channel: SPWM channel(SPWM_CH_0~3)
 * @param[in] ditherVal: channel dither value
 * @return None
 */
static inline void SPWM_REG_SetChDither(SPWM_Type* regBase, spwm_channel_t channel, uint8_t ditherVal)
{
    regBase->CHDITHER[channel] = (uint32_t)ditherVal & SPWM_CH0DITHER_CHDITHER_Msk;
}

/*!
 * @brief Set the SPWM modulo dither value
 *
 * @param[in] regBase: The SPWM register base address
 * @param[in] ditherVal: modulo dither value
 * @return None
 */
static inline void SPWM_REG_SetMODDither(SPWM_Type* regBase, uint8_t ditherVal)
{
    regBase->MODDITHER = (uint32_t)ditherVal;
}
#if defined(__cplusplus)
}
#endif

#endif /* SPWM_REG_ACCESS_H */

/*******EOF********************************************************************/

